# -*- coding: utf-8 -*-
"""
主题管理器模块
功能：集中管理所有主题相关的操作，包括创建、编辑、删除、配置等
"""

import json
import time
from datetime import datetime
from typing import Dict, List, Optional, Any
import os
import sys

try:
    import pandas as pd
    PANDAS_AVAILABLE = True
except ImportError:
    PANDAS_AVAILABLE = False

from src.models.test_topic import TestTopic
from src.managers.config_manager import config_manager

class TopicManager:
    """主题管理器类"""
    
    def __init__(self):
        self.topics: Dict[str, TestTopic] = {}
        self.current_topic: Optional[TestTopic] = None
        self.load_topics()
    
    def load_topics(self, filename: str = "test_topics.json"):
        """从文件加载主题"""
        try:
            data = config_manager.load_config('topics')
            if data:
                for name, topic_data in data.items():
                    self.topics[name] = TestTopic.from_dict(topic_data)
                print(f"✅ 已加载 {len(self.topics)} 个主题")
            else:
                print("⚠️  没有找到主题配置文件")
        except Exception as e:
            print(f"❌ 加载主题失败: {e}")
    
    def save_topics(self):
        """保存主题到文件"""
        try:
            data = {name: topic.to_dict() for name, topic in self.topics.items()}
            config_manager.save_config('topics', data)
            print("✅ 主题已保存")
        except Exception as e:
            print(f"❌ 保存主题失败: {e}")
    
    def create_topic(self, name: str) -> bool:
        """创建新主题"""
        if name in self.topics:
            print(f"⚠️ 主题 '{name}' 已存在")
            return False
        
        self.topics[name] = TestTopic(name)
        print(f"✅ 主题 '{name}' 已创建")
        return True
    
    def delete_topic(self, name: str) -> bool:
        """删除主题"""
        if name in self.topics:
            del self.topics[name]
            print(f"✅ 主题 '{name}' 已删除")
            self.save_topics()
            return True
        else:
            print(f"⚠️ 主题 '{name}' 不存在")
            return False
    
    def list_topics(self):
        """列出所有主题"""
        if not self.topics:
            print("⚠️ 没有主题")
            return
        
        print(f"📊 共发现 {len(self.topics)} 个主题")
        print("=" * 50)
        
        for i, (name, topic) in enumerate(self.topics.items(), 1):
            cmd_count = len(topic.commands)
            pattern_count = len(topic.parse_patterns)
            
            print(f"{i}. 📁 {name}")
            print(f"   ├─ 指令数量: {cmd_count} 条")
            print(f"   ├─ 解析模式: {pattern_count} 个")
            
            # 显示详细指令信息
            if topic.commands:
                print("   └─ 指令详情:")
                for j, cmd in enumerate(topic.commands, 1):
                    loop_count = cmd.get("loop_count", 1)
                    print(f"      {j}. 📡 {cmd['command']}")
                    print(f"         ⏱️  延时: {cmd['delay_ms']}ms")
                    print(f"         🔁 循环: {loop_count}次")
            
            # 显示解析模式详情
            if topic.parse_patterns:
                print("   └─ 解析模式:")
                for j, pattern in enumerate(topic.parse_patterns, 1):
                    print(f"      {j}. 🔍 {pattern['name']} ({pattern['type']})")
                    print(f"         📝 正则: {pattern['pattern']}")
            
            if i < len(self.topics):
                print()
    
    def view_topic_details(self, topic_name: str):
        """查看主题详细内容"""
        if topic_name not in self.topics:
            print(f"⚠️ 主题 '{topic_name}' 不存在")
            return
        
        topic = self.topics[topic_name]
        
        while True:
            self._clear_screen()
            print(f"📋 主题详情: {topic_name}")
            print("=" * 60)
            
            # 指令信息
            print("📡 指令列表:")
            print("-" * 50)
            if topic.commands:
                for i, cmd in enumerate(topic.commands, 1):
                    desc = f" - {cmd['description']}" if cmd.get('description') else ""
                    loop_count = cmd.get("loop_count", 1)
                    print(f"{i}. 📡 {cmd['command']}{desc}")
                    print(f"   ⏱️  延时: {cmd['delay_ms']}ms")
                    print(f"   🔁 循环: {loop_count}次")
            else:
                print("⚠️  该主题没有指令")
            
            # 解析模式信息
            print("\n🔍 解析模式:")
            print("-" * 40)
            if topic.parse_patterns:
                for i, pattern in enumerate(topic.parse_patterns, 1):
                    print(f"{i}. 🔍 {pattern['name']} ({pattern['type']})")
                    print(f"    📝 正则: {pattern['pattern']}")
            else:
                print("⚠️  该主题没有配置解析模式")
            
            # 操作菜单
            print("\n" + "=" * 60)
            print("🔧 快速操作:")
            print("1. ➕ 添加指令")
            if topic.commands:
                print("2. 📝 修改指令")
                print("3. 🗑️  删除指令")
                print("4. ⬆️  插入指令")
            print("5. 🔍 配置解析模式")
            print("6. 🔁 配置循环参数")
            print("7. 👈 返回")
            
            choice = input("\n请选择操作 (1-7): ").strip()
            
            if choice == '1':
                self._add_command_to_topic(topic)
            elif choice == '2' and topic.commands:
                self._modify_command_by_index(topic)
            elif choice == '3' and topic.commands:
                self._delete_command_by_index(topic)
            elif choice == '4' and topic.commands:
                self._insert_command_by_index(topic)
            elif choice == '5':
                self._configure_parse_patterns(topic)
            elif choice == '6':
                self._configure_loop_parameters(topic)
            elif choice == '7':
                break
            else:
                print("❌ 无效选择")
    
    def configure_topic(self, topic_name: str):
        """配置主题"""
        if topic_name not in self.topics:
            print(f"⚠️ 主题 '{topic_name}' 不存在")
            return
        
        topic = self.topics[topic_name]
        self.current_topic = topic
        
        while True:
            print(f"\n📝 编辑主题: {topic_name}")
            print("="*50)
            print("1. 查看所有指令")
            print("2. 添加指令")
            print("3. 插入指令")
            print("4. 修改指令")
            print("5. 删除指令")
            print("6. 配置解析模式")
            print("7. 🔁 配置循环参数")
            print("8. 返回上级菜单")
            
            choice = input("请选择操作 (1-8): ").strip()
            
            if choice == '1':
                self._show_topic_commands(topic)
            elif choice == '2':
                self._add_command_to_topic(topic)
            elif choice == '3':
                self._insert_command_to_topic(topic)
            elif choice == '4':
                self._modify_command_in_topic(topic)
            elif choice == '5':
                self._delete_command_from_topic(topic)
            elif choice == '6':
                self._configure_parse_patterns(topic)
            elif choice == '7':
                self._configure_loop_parameters(topic)
            elif choice == '8':
                break
            else:
                print("❌ 无效选择")
    
    def _show_topic_commands(self, topic: TestTopic):
        """显示主题的所有指令"""
        if not topic.commands:
            print("⚠️  该主题没有指令")
            return
        
        print(f"\n📋 主题 '{topic.name}' 的指令列表:")
        print("-" * 75)
        print(f"{'序号':<4} {'指令':<25} {'延时(ms)':<10} {'循环次数':<8} {'描述'}")
        print("-" * 75)
        
        for i, cmd in enumerate(topic.commands):
            desc = cmd.get("description", "无")
            loop_count = cmd.get("loop_count", 1)
            print(f"{i+1:<4} {cmd['command']:<32} {cmd['delay_ms']:<12} {loop_count:<8} {desc}")
    
    def _add_command_to_topic(self, topic: TestTopic):
        """向主题添加指令"""
        command = input("请输入AT指令: ").strip()
        if not command:
            return
        
        try:
            delay_ms = int(input("请输入延时时间(ms): ").strip())
            description = input("请输入描述(可选): ").strip()
            loop_str = input("请输入循环次数(默认1): ").strip()
            loop_count = int(loop_str) if loop_str else 1
            
            topic.add_command(command, delay_ms, description, loop_count)
            print("✅ 指令已添加")
            self.save_topics()
        except ValueError:
            print("❌ 无效的延时时间或循环次数")
    
    def _insert_command_to_topic(self, topic: TestTopic):
        """向主题插入指令"""
        self._show_topic_commands(topic)
        
        try:
            index = int(input("请输入插入位置(从1开始): ").strip()) - 1
            command = input("请输入AT指令: ").strip()
            delay_ms = int(input("请输入延时时间(ms): ").strip())
            description = input("请输入描述(可选): ").strip()
            loop_str = input("请输入循环次数(默认1): ").strip()
            loop_count = int(loop_str) if loop_str else 1
            
            if topic.insert_command(index, command, delay_ms, description, loop_count):
                print("✅ 指令已插入")
                self.save_topics()
                input("按回车键继续...")
            else:
                print("❌ 插入位置无效")
                input("按回车键继续...")
        except ValueError:
            print("❌ 输入格式错误")
            input("按回车键继续...")
    
    def _modify_command_in_topic(self, topic: TestTopic):
        """修改主题中的指令"""
        self._show_topic_commands(topic)
        
        try:
            index = int(input("请输入要修改的指令序号: ").strip()) - 1
            if 0 <= index < len(topic.commands):
                print(f"当前指令: {topic.commands[index]['command']}")
                
                command = input("请输入新指令(留空保持不变): ").strip()
                if not command:
                    command = topic.commands[index]['command']
                
                delay_input = input("请输入新延时(ms, 留空保持不变): ").strip()
                delay_ms = int(delay_input) if delay_input else topic.commands[index]['delay_ms']
                
                description = input("请输入新描述(留空保持不变): ").strip()
                if not description:
                    description = topic.commands[index].get('description', '')
                
                loop_input = input("请输入循环次数(留空保持不变): ").strip()
                loop_count = int(loop_input) if loop_input else topic.commands[index].get('loop_count', 1)
                
                topic.update_command(index, command, delay_ms, description, loop_count)
                print("✅ 指令已修改")
                self.save_topics()
                input("按回车键继续...")
            else:
                print("❌ 指令序号无效")
                input("按回车键继续...")
        except ValueError:
            print("❌ 输入格式错误")
            input("按回车键继续...")
    
    def _delete_command_from_topic(self, topic: TestTopic):
        """删除主题中的指令"""
        self._show_topic_commands(topic)
        
        try:
            index = int(input("请输入要删除的指令序号: ").strip()) - 1
            deleted = topic.delete_command(index)
            if deleted:
                print(f"✅ 已删除指令: {deleted['command']}")
                self.save_topics()
                input("按回车键继续...")
            else:
                print("❌ 指令序号无效")
                input("按回车键继续...")
        except ValueError:
            print("❌ 输入格式错误")
            input("按回车键继续...")
    
    def _modify_command_by_index(self, topic: TestTopic):
        """通过序号修改指令"""
        try:
            index = int(input("请输入要修改的指令序号(1-{}): ".format(len(topic.commands))).strip()) - 1
            if 0 <= index < len(topic.commands):
                cmd = topic.commands[index]
                print(f"\n📝 修改指令 #{index+1}")
                print(f"当前: {cmd['command']} (延时: {cmd['delay_ms']}ms)")
                
                new_cmd = input("新指令(留空不变): ").strip()
                if not new_cmd:
                    new_cmd = cmd['command']
                
                delay_str = input("新延时ms(留空不变): ").strip()
                delay_ms = int(delay_str) if delay_str else cmd['delay_ms']
                
                desc = input("新描述(留空不变): ").strip()
                if not desc:
                    desc = cmd.get('description', '')
                
                loop_str = input("循环次数(留空不变): ").strip()
                loop_count = int(loop_str) if loop_str else cmd.get('loop_count', 1)
                
                topic.update_command(index, new_cmd, delay_ms, desc, loop_count)
                print("✅ 修改成功！")
                self.save_topics()
                time.sleep(1)
            else:
                print("❌ 序号无效")
                time.sleep(1)
        except ValueError:
            print("❌ 请输入有效数字")
            time.sleep(1)
        except KeyboardInterrupt:
            pass
    
    def _delete_command_by_index(self, topic: TestTopic):
        """通过序号删除指令"""
        try:
            index = int(input("请输入要删除的指令序号(1-{}): ".format(len(topic.commands))).strip()) - 1
            if 0 <= index < len(topic.commands):
                cmd = topic.commands[index]
                confirm = input(f"确定删除指令 #{index+1}: {cmd['command']}? (y/n): ").strip().lower()
                if confirm == 'y':
                    deleted = topic.delete_command(index)
                    self.save_topics()
                    print("✅ 删除成功！")
                    time.sleep(1)
            else:
                print("❌ 序号无效")
                time.sleep(1)
        except ValueError:
            print("❌ 请输入有效数字")
            time.sleep(1)
        except KeyboardInterrupt:
            pass
    
    def _insert_command_by_index(self, topic: TestTopic):
        """通过序号插入指令"""
        try:
            print(f"\n⬆️  插入指令")
            if topic.commands:
                print("当前指令位置:")
                for i, cmd in enumerate(topic.commands, 1):
                    print(f"  {i}. {cmd['command']}")
                print(f"  {len(topic.commands)+1}. 末尾")
            
            pos = int(input(f"插入到哪个位置(1-{len(topic.commands)+1}): ").strip()) - 1
            if 0 <= pos <= len(topic.commands):
                command = input("请输入AT指令: ").strip()
                delay_ms = int(input("请输入延时时间(ms): ").strip())
                description = input("请输入描述(可选): ").strip()
                loop_str = input("请输入循环次数(默认1): ").strip()
                loop_count = int(loop_str) if loop_str else 1
                
                topic.insert_command(pos, command, delay_ms, description, loop_count)
                self.save_topics()
                print("✅ 插入成功！")
                time.sleep(1)
            else:
                print("❌ 位置无效")
                time.sleep(1)
        except ValueError:
            print("❌ 请输入有效数字")
            time.sleep(1)
        except KeyboardInterrupt:
            pass
    
    def configure_parse_patterns(self, topic_name: str):
        """配置指定主题的解析模式（公共接口）"""
        topic = self.get_topic(topic_name)
        if topic:
            self._configure_parse_patterns(topic)
        else:
            print(f"❌ 主题 '{topic_name}' 不存在")

    def configure_topic(self, topic_name: str):
        """配置指定主题的所有参数（公共接口）"""
        topic = self.get_topic(topic_name)
        if topic:
            self._configure_topic(topic)
        else:
            print(f"❌ 主题 '{topic_name}' 不存在")

    def _configure_parse_patterns(self, topic: TestTopic):
        """配置数据解析模式"""
        print(f"\n🔍 配置主题 '{topic.name}' 的解析模式")
        print("="*60)
        
        # 显示教程
        print("📚 解析模式设置教程:")
        print("🎯 什么是解析模式？")
        print("   从设备响应中提取关键数据的规则，使用正则表达式")
        print("📋 常用模板:")
        print("   电压值: 名称=voltage, 正则=\\+CBC:\\s*(\\d+), 类型=int")
        print("   信号强度: 名称=rssi, 正则=\\+CSQ:\\s*(\\d+), 类型=int") 
        print("   版本号: 名称=version, 正则=Revision:\\s*(\\S+), 类型=str")
        print("   电池电量: 名称=battery, 正则=(\\d+)%, 类型=int")
        print("   温度值: 名称=temp, 正则=(\\d+\\.?\\d*)°C, 类型=float")
        print("-" * 60)
        
        while True:
            print("\n📊 当前解析模式:")
            if topic.parse_patterns:
                for i, pattern in enumerate(topic.parse_patterns, 1):
                    print(f"{i}. 🔹 {pattern['name']}: {pattern['pattern']} ({pattern['type']})")
            else:
                print("⚠️  尚未配置解析模式")
            
            print("\n🛠️  操作选项:")
            print("1. ➕ 自定义添加")
            print("2. ⚡ 快速模板")
            print("3. ✏️  重命名模式")
            print("4. ❌ 删除模式")
            print("5. 👈 返回上级")
            
            choice = input("请选择操作 (1-5): ").strip()
            
            if choice == '1':
                self._add_custom_pattern(topic)
            elif choice == '2':
                self._add_template_pattern(topic)
            elif choice == '3':
                self._rename_pattern(topic)
            elif choice == '4':
                self._delete_pattern(topic)
            elif choice == '5':
                break
    
    def _add_custom_pattern(self, topic: TestTopic):
        """添加自定义解析模式"""
        print("\n🎯 快速添加解析模式")
        print("💡 示例: 对于 '+ECADC: VBAT, 3739' 这样的数据")
        print("   输入名称: vbat_value")
        print("   输入关键词: VBAT, 或 ECADC")
        print("   将自动提取后面的数字")
        
        name = input("📋 数据名称: ").strip()
        if not name:
            print("❌ 数据名称不能为空")
            return
            
        # 提供智能建议
        keyword = input("🔍 数据中的关键词 (如VBAT, ECADC): ").strip()
        if keyword:
            # 自动生成正则表达式
            pattern = f"{keyword}[,:\\s]*(\\d+)"
            print(f"✅ 自动生成正则: {pattern}")
            
            print("📊 数据类型:")
            print("1. 整数(int) - 如3739")
            print("2. 浮点数(float) - 如37.39")
            print("3. 字符串(str) - 文本")
            
            type_choice = input("选择类型(1-3, 默认1): ").strip()
            type_map = {'1': 'int', '2': 'float', '3': 'str'}
            data_type = type_map.get(type_choice, 'int')
            
            topic.add_parse_pattern(name, pattern, data_type)
            self.save_topics()
            print(f"✅ 已添加: {name} ({data_type}) - 将提取{keyword}后的数值")
        else:
            # 回退到手动输入
            pattern = input("🔍 手动输入正则表达式: ").strip()
            if pattern:
                topic.add_parse_pattern(name, pattern, 'int')
                self.save_topics()
                print(f"✅ 已添加: {name}")
            else:
                print("❌ 正则表达式不能为空")
    
    def _add_template_pattern(self, topic: TestTopic):
        """使用模板快速添加解析模式"""
        templates = [
            {"name": "电压值", "pattern": r"\+CBC:\s*(\d+)", "type": "int", "desc": "提取+CBC后的电压值"},
            {"name": "信号强度", "pattern": r"\+CSQ:\s*(\d+)", "type": "int", "desc": "提取+CSQ后的信号强度"},
            {"name": "版本号", "pattern": r"Revision:\s*(\S+)", "type": "str", "desc": "提取版本信息"},
            {"name": "电池电量", "pattern": r"(\d+)%", "type": "int", "desc": "提取百分比电量"},
            {"name": "温度值", "pattern": r"(\d+\.?\d*)°C", "type": "float", "desc": "提取温度值"},
            {"name": "IMEI", "pattern": r"\+GSN:\s*(\d+)", "type": "str", "desc": "提取IMEI号码"},
            {"name": "一键VBAT", "pattern": r"VBAT,\s*(\d+)", "type": "int", "desc": "一键提取VBAT电压值"}
        ]
        
        print("\n🎯 快速模板添加")
        print("=" * 50)
        for i, template in enumerate(templates, 1):
            print(f"{i}. {template['name']} - {template['desc']}")
            print(f"   正则: {template['pattern']} ({template['type']})")
            print()
        
        try:
            choice = int(input("选择模板(1-7): ").strip())
            if 1 <= choice <= len(templates):
                template = templates[choice-1]
                topic.add_parse_pattern(template['name'], template['pattern'], template['type'])
                self.save_topics()
                print(f"✅ 已添加模板: {template['name']}")
            else:
                print("❌ 无效选择")
        except ValueError:
            print("❌ 请输入有效数字")
    
    def _delete_pattern(self, topic: TestTopic):
        """删除解析模式"""
        if not topic.parse_patterns:
            print("⚠️ 没有可删除的模式")
            return
            
        print("\n❌ 删除解析模式")
        for i, pattern in enumerate(topic.parse_patterns, 1):
            print(f"{i}. {pattern['name']}")
        
        try:
            choice = int(input("选择要删除的序号: ").strip()) - 1
            if 0 <= choice < len(topic.parse_patterns):
                deleted = topic.parse_patterns.pop(choice)
                topic.last_modified = datetime.now()
                self.save_topics()
                print(f"✅ 已删除: {deleted['name']}")
            else:
                print("❌ 序号无效")
        except ValueError:
            print("❌ 请输入有效数字")
    
    def _rename_pattern(self, topic: TestTopic):
        """重命名解析模式"""
        if not topic.parse_patterns:
            print("⚠️ 没有可重命名的模式")
            return
            
        print("\n✏️  重命名解析模式")
        for i, pattern in enumerate(topic.parse_patterns, 1):
            print(f"{i}. {pattern['name']} (正则: {pattern['pattern']})")
        
        try:
            choice = int(input("选择要重命名的序号: ").strip()) - 1
            if 0 <= choice < len(topic.parse_patterns):
                old_name = topic.parse_patterns[choice]['name']
                new_name = input(f"将 '{old_name}' 重命名为: ").strip()
                if new_name:
                    topic.parse_patterns[choice]['name'] = new_name
                    topic.last_modified = datetime.now()
                    self.save_topics()
                    print(f"✅ 已重命名: '{old_name}' → '{new_name}'")
                else:
                    print("❌ 名称不能为空")
            else:
                print("❌ 序号无效")
        except ValueError:
            print("❌ 请输入有效数字")
    
    def _configure_loop_parameters(self, topic: TestTopic):
        """配置循环参数"""
        print(f"\n🔁 配置主题 '{topic.name}' 的循环参数")
        print("=" * 40)
        
        print(f"当前设置:")
        print(f"   主题循环: {'启用' if topic.loop_enabled else '禁用'}")
        print(f"   循环次数: {topic.loop_count} ({'无限循环' if topic.loop_count == -1 else '次'})")
        print(f"   循环间隔: {topic.loop_delay_ms}ms")
        print(f"   错误停止: {'是' if topic.stop_on_error else '否'}")
        
        print("\n🛠️  设置选项:")
        print("1. 启用/禁用主题循环")
        print("2. 设置循环次数")
        print("3. 设置循环间隔")
        print("4. 设置错误处理")
        print("5. 返回")
        
        choice = input("选择操作 (1-5): ").strip()
        
        if choice == '1':
            topic.loop_enabled = not topic.loop_enabled
            print(f"✅ 主题循环已{'启用' if topic.loop_enabled else '禁用'}")
        elif choice == '2':
            count_str = input("循环次数 (-1=无限循环): ").strip()
            try:
                topic.loop_count = int(count_str)
                print(f"✅ 循环次数设置为: {topic.loop_count}")
            except ValueError:
                print("❌ 请输入有效数字")
        elif choice == '3':
            delay_str = input("循环间隔(ms): ").strip()
            try:
                topic.loop_delay_ms = int(delay_str)
                print(f"✅ 循环间隔设置为: {topic.loop_delay_ms}ms")
            except ValueError:
                print("❌ 请输入有效数字")
        elif choice == '4':
            topic.stop_on_error = not topic.stop_on_error
            print(f"✅ 错误时{'停止' if topic.stop_on_error else '继续'}执行")
        
        topic.last_modified = datetime.now()
        self.save_topics()
    
    def _configure_topic(self, topic: TestTopic):
        """配置主题的所有参数"""
        while True:
            print(f"\n⚙️  配置主题 '{topic.name}'")
            print("=" * 40)
            print("1. 📊 配置解析模式")
            print("2. 🔁 配置循环参数")
            print("3. 👈 返回")
            
            choice = input("请选择操作 (1-3): ").strip()
            
            if choice == '1':
                self._configure_parse_patterns(topic)
            elif choice == '2':
                self._configure_loop_parameters(topic)
            elif choice == '3':
                break
            else:
                print("❌ 无效选择")
    
    def get_topic(self, name: str) -> Optional[TestTopic]:
        """获取指定主题"""
        return self.topics.get(name)
    
    def get_all_topics(self) -> Dict[str, TestTopic]:
        """获取所有主题"""
        return self.topics
    
    def _clear_screen(self):
        """清屏"""
        os.system('cls' if os.name == 'nt' else 'clear')